using System.Reflection;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.ApplicationModels;

namespace Vin.Tool.AspNetCore.Conventions;

public class ApiControllerRouteConvention : IControllerModelConvention
{
    /// <summary>
    /// 目标API程序集。
    /// </summary>
    private readonly Assembly _apiAssembly;

    /// <summary>
    /// API前缀。
    /// </summary>
    private readonly string _apiPrefix;

    public ApiControllerRouteConvention(Assembly apiAssembly, string apiPrefix = "")
    {
        _apiAssembly = apiAssembly ?? throw new ArgumentNullException(nameof(apiAssembly));
        _apiPrefix = apiPrefix;
    }

    public void Apply(ControllerModel controller)
    {
        // 如果没有设置API前缀，则不进行处理
        if (string.IsNullOrEmpty(_apiPrefix)) return;
        // 如果当前Action不属于目标API程序集，则不进行处理
        if (controller.ControllerType.Assembly != _apiAssembly) return;
        // 处理控制器
        var isHandleController = HandleController(controller);
        // 处理动作
        foreach (var actionModel in controller.Actions)
        {
            HandleAction(actionModel, isHandleController);
        }
    }

    private bool HandleController(ControllerModel controlerModel)
    {
        var routeAttribute = controlerModel.Attributes
            .OfType<RouteAttribute>()
            .FirstOrDefault();
        if (routeAttribute == null) return false;

        // 处理控制器的路由模板
        foreach (var selector in controlerModel.Selectors)
        {
            HandleSelector(selector, $"{_apiPrefix}/[controller]");
        }

        return true;
    }

    private void HandleAction(ActionModel action, bool isHandleController)
    {
        // 设置路由模板
        foreach (var selector in action.Selectors)
        {
            if (selector.AttributeRouteModel == null)
                selector.AttributeRouteModel = new AttributeRouteModel();
            // 原始的路由模板
            var originalTemplate = selector.AttributeRouteModel.Template ?? string.Empty;
            var defaultTemplate =
                $"{_apiPrefix}{(originalTemplate.StartsWith("/") ? originalTemplate : $"/{originalTemplate}")}";
            // 如果原始模版以斜杠开头，则处理动作的模板
            if (originalTemplate.StartsWith("/"))
            {
                HandleSelector(selector, defaultTemplate, "/");
            }
            // 如果没有处理控制器，则处理动作的模板
            else if (!isHandleController)
            {
                HandleSelector(selector, defaultTemplate);
            }
        }
    }

    private void HandleSelector(SelectorModel selector, string defaultTemplate, string apiPrefix = "")
    {
        if (selector.AttributeRouteModel == null)
            selector.AttributeRouteModel = new AttributeRouteModel();
        // 原始的路由模板
        var originalTemplate = selector.AttributeRouteModel.Template;
        // 如果原始模板为空，则初始化为API前缀
        if (!string.IsNullOrEmpty(originalTemplate))
        {
            // 添加前缀（例如：将 "Home/Index" 改为 "api2/Home/Index"）
            selector.AttributeRouteModel.Template =
                $"{apiPrefix}{_apiPrefix}{(originalTemplate.StartsWith("/") ? originalTemplate : $"/{originalTemplate}")}";
        }
        else
        {
            // 如果没有定义路由模板，直接使用前缀+控制器+动作
            selector.AttributeRouteModel = new AttributeRouteModel
            {
                Template = defaultTemplate
            };
        }
    }
}